﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PayloadTracker.Tiles
{
    public delegate void TileInvalidatedDelegate(Tile t);

    public class Tile
    {
        public static readonly int SIZE = 256;

        static System.Drawing.Image m_ErrorImage, m_LoadingImage;

        Uri m_URL;
        string m_SavePath;
        System.Net.WebClient m_Wc;
        bool m_IsImageReady = false;
        System.Drawing.Image m_Image;
        Coordinate m_UL;
        Coordinate m_LR;

        public event TileInvalidatedDelegate OnTileInvalidated;
        public bool IsImageReady { get { return m_IsImageReady; } }
        public System.Drawing.Image Image {get{return m_Image;}}
        public Coordinate UL { get { return m_UL; } }
        public Coordinate LR {get{return m_LR;}}


        public Tile(System.Drawing.Image img, Coordinate ul, Coordinate lr)
        {
            m_Image = img;
            m_UL = ul;
            m_LR = lr;
            m_IsImageReady = true;
        }
        public Tile(System.Uri url, string savePath,Coordinate ul, Coordinate lr, bool async)
        {
            m_URL = url;
            m_UL = ul;
            m_LR = lr;
            m_SavePath = savePath;
            m_Wc = new System.Net.WebClient();
            m_Wc.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(m_Wc_DownloadFileCompleted);
            m_Wc.Headers.Add("user-agent", "PayloadTracker/" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString());
            try
            {
                Logger.LOG.WriteLine("Downloading Tile: " + url);
                if (async)
                {
                    m_Wc.DownloadFileAsync(url, savePath);
                    m_Image = GetLoadingImage();
                }
                else
                {
                    m_Wc.DownloadFile(url, savePath);
                    m_Wc_DownloadFileCompleted(null, null);
                }

            }
            catch (System.Exception ex)
            {
                Logger.LOG.Error(string.Format("Failed to download tile {0} to {1} because of {2}", url.ToString(), savePath, ex));

                if (System.IO.File.Exists(savePath))
                    System.IO.File.Delete(savePath);

                m_Image = GetErrorImage();
                m_IsImageReady = false;
            }
            
        }

        void m_Wc_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {

            
            if( e != null && e.Error != null)
            {
                Logger.LOG.Error(string.Format("Failed to download file at {0} due to: {1}", m_URL, e.Error));
                if (System.IO.File.Exists(m_SavePath))
                    System.IO.File.Delete(m_SavePath);

                m_Image = GetErrorImage();

                return;
            }


            try
            {
                m_Image = System.Drawing.Image.FromFile(m_SavePath);
                m_IsImageReady = true;
                TileInvalidatedDelegate del = OnTileInvalidated;
                if (del != null)
                    del(this);
            }
            catch (System.Exception ex)
            {
                Logger.LOG.Error("Failed opening tile: " + m_SavePath + " from cache deleting entry. " + ex.ToString());
                if (System.IO.File.Exists(m_SavePath))
                    System.IO.File.Delete(m_SavePath);
                m_Image = GetErrorImage();
            }
        }
        private System.Drawing.Image GetErrorImage()
        {
            if (m_ErrorImage == null)
            {
                var bmp = new System.Drawing.Bitmap(Tile.SIZE, Tile.SIZE);
                var gfx = System.Drawing.Graphics.FromImage(bmp);

                gfx.FillRectangle(System.Drawing.Brushes.Transparent, 0, 0, Tile.SIZE, Tile.SIZE);
                gfx.DrawString("Error", System.Drawing.SystemFonts.DefaultFont, System.Drawing.Brushes.Black, 0, 0);

                m_ErrorImage = bmp;
            }

            return m_ErrorImage;
        }
        private System.Drawing.Image GetLoadingImage()
        {
            if (m_LoadingImage == null)
            {
                var bmp = new System.Drawing.Bitmap(Tile.SIZE, Tile.SIZE);
                var gfx = System.Drawing.Graphics.FromImage(bmp);

                gfx.FillRectangle(System.Drawing.Brushes.Transparent, 0, 0, Tile.SIZE, Tile.SIZE);
                m_LoadingImage = bmp;
            }

            return m_LoadingImage;
        }
    }
}
